//=============================================================================================
/**
 * @file	debug_3d_draw_count.c
 * @brief	デバッグ用描画関連カウント（ポリゴン数とか）
 */
//=============================================================================================
#ifdef PM_DEBUG

#include <nitro.h>
#include <nnsys.h>
#include "debug_3d_draw_count.h"
#include "assert.h"

//----- ポリゴン描画の回数を調べるためのDEBUG処理
typedef struct{
	int NNS_AddVertexNum;
	int NNS_AddPolygonNum;
	int NNS_AddDrawNum;
	int VertexNum;
	int PolygonNum;
	int DrawNum;

	int TexBlock;
	int PlttBlock;

	NNSiGfdLnkVramBlock *texture_p;
	NNSiGfdLnkVramBlock *pal_p;
	int MustSpaceSize;
	GF_G3DMAN_MODE TexManMode;
	GF_G3DMAN_MODE PltManMode;
	int FrmPltSize;
}DEBUG_DRAW_COUNT;

static DEBUG_DRAW_COUNT DebugDrawCount;

static void DumpCallBack(u32 addr, u32 szByte, void* pUserData );
static void FrmPltDumpCallBack(u32 loAddr, u32 hiAddr, u32 szFree, u32 szTotal );
static void FrmTexDumpCallBack(	int index, u32 startAddr, u32 endAddr,
								u32 blockMax, BOOL bActive, void* pUserData );

//------------------------------------------------------------------
/**
 * 3D描画のために調べた数値を退避
 *
*/
//------------------------------------------------------------------
void D_3D_DC_DrawPolygonCountUp(void)
{
	DebugDrawCount.NNS_AddVertexNum  = DebugDrawCount.VertexNum;
	DebugDrawCount.NNS_AddPolygonNum = DebugDrawCount.PolygonNum;
	DebugDrawCount.NNS_AddDrawNum       = DebugDrawCount.DrawNum;

	DebugDrawCount.VertexNum  = 0;
	DebugDrawCount.PolygonNum = 0;
	DebugDrawCount.DrawNum    = 0;
}

//------------------------------------------------------------------
/**
 * NITROSYSTEMに渡したポリゴンの数を返す
 *
 * @param	int ポリゴン数
*/
//------------------------------------------------------------------
int D_3D_DC_DrawPolygonGet(void)
{
	return DebugDrawCount.NNS_AddPolygonNum;
}

//------------------------------------------------------------------
/**
 * NITROSYSTEMに渡した頂点の数を返す
 *
 * @param	int	頂点数
*/
//------------------------------------------------------------------
int D_3D_DC_DrawVertexGet(void)
{
	return DebugDrawCount.NNS_AddVertexNum;
}

//------------------------------------------------------------------
/**
 * NITROSYSTEMからポリゴン描画した回数を返す
 *
 * @return	int	描画数
*/
//------------------------------------------------------------------
int D_3D_DC_DrawNumGet(void)
{
	return DebugDrawCount.NNS_AddDrawNum;
}

//==============================================================================
/**
 * リンクドＶＲＡＭマネージャーとパレットマネージャーのポインタを保存
 *
 * @param   texp		テクスチャマネージャー
 * @param   palp		パレットマネージャー
 * @param	inTexBlock	テクスチャブロックサイズ
 * @param	inPlttBlockSize	パレットブロックサイズ
 *
 * @retval  none
 */
//==============================================================================
void D_3D_DC_VramManPSet(NNSiGfdLnkVramBlock *texp, NNSiGfdLnkVramBlock *palp,
						const int inTexBlock, const int inPlttBlock)
{
	DebugDrawCount.texture_p = texp;
	DebugDrawCount.pal_p     = palp;
	DebugDrawCount.TexBlock  = inTexBlock;
	DebugDrawCount.PlttBlock  = inPlttBlock;
	OS_Printf("V = %d\n",D_3D_DC_VramTexBlankSizeGet());
	DebugDrawCount.MustSpaceSize = 0;
}

//==============================================================================
/**
 * 必ず確保しておきたいテクスチャVRAMの空き容量(バイト)をセット
 *
 * @param   inSize		確保しておきたいバイトサイズ
 *
 * @retval  none
 */
//==============================================================================
void D_3D_DC_SetMustSpaceTexVramSize(const int inSize)
{
	DebugDrawCount.MustSpaceSize = inSize;
}

//==============================================================================
/**
 * VRAMへのテクスチゃ転送状態を取得する
 *
 *
 * @retval  int		使用しているＶＲＡＭ容量
 */
//==============================================================================
int  D_3D_DC_VramTexSizeGet(void)
{
	int size;
	size = D_3D_DC_VramTexBlankSizeGet();
#if 0
	int size = 0;
	int i;

	NNSiGfdLnkVramBlock *tex = DebugDrawCount.texture_p;


	for(i=0;i<DebugDrawCount.TexBlock;i++){
		//リンクドVRAMマネージャーの先頭を探す
		if((tex->pBlkPrev==0 && tex->pBlkNext!=0) || (tex->pBlkPrev==0 && tex->pBlkNext==0)){
			break;
		}
		tex++;
	}

	while(tex->pBlkNext!=0){	// リンクが続く限り足して次へ渡っていく
		size += tex->szByte;
		tex = (NNSiGfdLnkVramBlock *)tex->pBlkNext;
	}
	size += tex->szByte;		//最後のリンク先のVRAM転送数も足す

	OS_Printf("Vram_Tex=%d:%d\n",(DebugDrawCount.TexBlock*1024)-size,size);
#endif
	// VRAMマネージャーが保存しているのは「使用していない量」なので総量から引いて返す
	return (DebugDrawCount.TexBlock*1024)-size;

}

//==============================================================================
/**
 * VRAMへのテクスチゃ転送状態を取得する
 *
 *
 * @retval  int		ＶＲＡＭ余り
 */
//==============================================================================
int  D_3D_DC_VramTexBlankSizeGet(void)
{
	int size;
	size = 0;
	if ( D_3D_DC_GetTexManType() == GF_G3DMAN_LNK ){
		NNS_GfdDumpLnkTexVramManagerEx( DumpCallBack, NULL , &size );
	}else{
		NNS_GfdDumpFrmTexVramManagerEx( FrmTexDumpCallBack, &size );
	}

	size -= DebugDrawCount.MustSpaceSize;
#if 1
	GF_ASSERT_MSG(size >=0 , "VRAMを使い切りました。\n");
#else
	if (size < 0){
		OS_Printf("VRAMを使い切りました。\n");
	}
#endif
	return size;
}


//==============================================================================
/**
 * リンクドPALマネージャーの転送状態を取得する
 *
 *
 * @retval  int		リンクドPALマネージャーの転送バイト数
 */
//==============================================================================
int  D_3D_DC_VramPalSizeGet(void)
{
	int size;
	size = D_3D_DC_VramPalBlankSizeGet();
#if 0
	int i;

	NNSiGfdLnkVramBlock *tex = DebugDrawCount.pal_p;


	for(i=0;i<DebugDrawCount.PlttBlock;i++){
		//リンクドPALLマネージャーの先頭を探す
		if((tex->pBlkPrev==0 && tex->pBlkNext!=0) || (tex->pBlkPrev==0 && tex->pBlkNext==0)){
			break;
		}
		tex++;
	}

	while(tex->pBlkNext!=0){	// リンクが続く限り足して次へ渡っていく
		size += tex->szByte;
		tex = (NNSiGfdLnkVramBlock *)tex->pBlkNext;
	}
	size += tex->szByte;		//最後のリンク先のVRAM転送数も足す
#endif
	// PALマネージャーが保存しているのは「使用していない量」なので総量から引いて返す
	return (DebugDrawCount.PlttBlock*1024)-size;
}

//==============================================================================
/**
 * PALマネージャーの転送状態を取得する
 *
 *
 * @retval  int		パレット余りサイズ
 */
//==============================================================================
int  D_3D_DC_VramPalBlankSizeGet(void)
{
	int size = 0;
	if ( D_3D_DC_GetPltManType() == GF_G3DMAN_LNK ){
		NNS_GfdDumpLnkPlttVramManagerEx( DumpCallBack, &size );
	}else{
		NNS_GfdDumpFrmPlttVramManagerEx( FrmPltDumpCallBack );
		size = DebugDrawCount.FrmPltSize;
	}
	return size;
}

//==============================================================================
/**
 * リンクドVRAMマネージャの内部情報を取得するためのコールバック
 *
 *
 * @retval  none
 */
//==============================================================================
static void DumpCallBack(u32 addr, u32 szByte, void* pUserData )
{
	// 合計サイズを計算
    (*((u32*)pUserData)) += szByte;
}

//==============================================================================
/**
 * フレームパレットVRAMマネージャの内部情報を取得するためのコールバック
 *
 *
 * @retval  none
 */
//==============================================================================
static void FrmPltDumpCallBack(u32 loAddr, u32 hiAddr, u32 szFree, u32 szTotal )
{
	// 合計サイズを計算
    DebugDrawCount.FrmPltSize += szFree;
}

//==============================================================================
/**
 * フレームテクスチャVRAMマネージャの内部情報を取得するためのコールバック
 *
 *
 * @retval  none
 */
//==============================================================================
void FrmTexDumpCallBack(	int index, u32 startAddr, u32 endAddr,
							u32 blockMax, BOOL bActive, void* pUserData )
{
	if( bActive ){
		// 合計サイズを計算
		(*((u32*)pUserData)) += (endAddr - startAddr);
    }
}


//==============================================================================
/**
 * カウントアップ
 *
 * @param   object_p		レンダーＯＢＪ
 *
 * @retval  none
 */
//==============================================================================
void D_3D_DC_CountNum(NNSG3dRenderObj* object_p)
{
	//モデリングデータリソースから頂点数を取得して足す
	DebugDrawCount.VertexNum  += object_p->resMdl->info.numVertex;
	//モデリングデータリソースからポリゴン数を取得して足す
	DebugDrawCount.PolygonNum += object_p->resMdl->info.numPolygon;
	DebugDrawCount.DrawNum++;
}

//==============================================================================
/**
 * テクスチャマネージャタイプセット
 *
 * @param   mode	マネージャモード
 *
 * @retval  none
 */
//==============================================================================
void D_3D_DC_SetTexManType(GF_G3DMAN_MODE mode)
{
	DebugDrawCount.TexManMode = mode;
}

//==============================================================================
/**
 * パレットマネージャタイプセット
 *
 * @param   mode	マネージャモード
 *
 * @retval  none
 */
//==============================================================================
void D_3D_DC_SetPltManType(GF_G3DMAN_MODE mode)
{
	DebugDrawCount.PltManMode = mode;
}

//==============================================================================
/**
 * テクスチャマネージャタイプ取得
 *
 * @retval  GF_G3DMAN_MODE		マネージャタイプ
 */
//==============================================================================
GF_G3DMAN_MODE D_3D_DC_GetTexManType(void)
{
	return DebugDrawCount.TexManMode;
}

//==============================================================================
/**
 * パレットマネージャタイプ取得
 *
 * @retval  GF_G3DMAN_MODE		マネージャタイプ
 */
//==============================================================================
GF_G3DMAN_MODE D_3D_DC_GetPltManType(void)
{
	return DebugDrawCount.PltManMode;
}

#endif	//PM_DEBUG
